//////////////////////////////////////////////////////////////////////////////////////////////
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//	File			:	"GameFont.h"
//	Authors			:	Jake Castillo,
//	Project			:	Project Aetheryte
//	Date Modified	:	8/6/2013
//	Purpose			:	Font seen when in gameplay.
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//////////////////////////////////////////////////////////////////////////////////////////////

#include "GameFont.h"
#include "../SGD Wrappers/CSGD_TextureManager.h"
#include <cassert>

GameFont::GameFont(void)
{
}


GameFont::~GameFont(void)
{
}

void GameFont::Initialize( const TCHAR* szFilepath, int nWidth,  
								int nHeight,  int nCols, int nRows, bool OnlyUpper, 
								TCHAR cFirstChar, unsigned int lang )	
{
	// Load the image
	m_nImageID = CSGD_TextureManager::GetInstance()->LoadTexture(
					szFilepath,	D3DCOLOR_ARGB(255, 0, 0, 0) );
	
	// Validate
	assert( m_nImageID != -1 && "CBitmapFont::Draw - image was not loaded." );

	m_nCharWidth		= nWidth;
	m_nCharHeight		= nHeight;
	m_nNumCols			= nCols;
	m_nNumRows			= nRows;

	m_bOnlyUppercase	= OnlyUpper;
	m_cFirstChar		= cFirstChar;

	language = lang;

	CreateLookup();
}

void GameFont::Terminate( void )	
{
	CSGD_TextureManager::GetInstance()->UnloadTexture( m_nImageID );
	m_nImageID = -1;

	for(int i = 0; i < m_nNumRows; i++)
	{
		delete[] LookupTable[i];
	}
	
	delete[] LookupTable;
}

void GameFont::Draw( const TCHAR* strOut, int nX, int nY, float fScale, DWORD dwColor ) const			
{
	// Validate
	assert( m_nImageID != -1 && "CBitmapFont::Draw - image was not loaded." );
	assert( strOut != nullptr && "CBitmapFont::Draw - string cannot be null." );

	// Store the starting x location
	int nColStart = nX;
	float X = (float)nX;
	float Y = (float)nY;

	// Iterate through the string until reaching the null terminator.
	for( int i = 0; strOut[ i ]; i++ )
	{
		// Get the character from the array
		TCHAR ch = strOut[ i ];

		// Check for white space
		if( ch == _T(' ') )
		{
			//X += (float)m_nCharWidth * fScale;
			X += LookupTable[0][0] * fScale;
			continue;
		}
		else if( ch == _T('\n') )
		{
			Y += (float)m_nCharHeight * fScale;
			X = (float)nColStart;
			continue;
		}
		else if( ch == _T('\t') )
		{
			// Calculate the number of characters printed
			float curr = (X - nColStart) / (m_nCharHeight * fScale);

			// Calculate the spaces to add
			int spaces = 4 - ((int)curr % 4);

			// Move that many spaces
			X += (float)spaces * (float)LookupTable[0][0] * fScale;
			continue;
		}
		else if( ch == _T('\0') )
		{
			return;
		}

		// Convert to uppercase?
		if( m_bOnlyUppercase == true )
			ch = TCTOUPPER( ch );

		// Calculate the cell ID based on the ASCII value
		int id = ch - m_cFirstChar;
		RECT rCell = CellAlgorithm( id );
		int newSize = LookupTable[id / m_nNumCols][id % m_nNumCols];

		// Draw the character
		CSGD_TextureManager::GetInstance()->Draw(
			m_nImageID, (int)X, (int)Y,
			fScale, fScale, &rCell,
			0.0f, 0.0f, 0.0f,
			dwColor );

		// Move to the next position
		X += newSize * fScale;
	}
}

RECT GameFont::CellAlgorithm( int id ) const				
{
	return Font::CellAlgorithm(id);
}

void GameFont::CreateLookup()
{
	int arrLookup[28][8];

	// Hard-coded lookup table
	arrLookup[0][0]  = 5;
	arrLookup[0][1]  = 6;
	arrLookup[0][2]  = 7;
	arrLookup[0][3]  = 9;
	arrLookup[0][4]  = 9;
	arrLookup[0][5]  = 15;
	arrLookup[0][6]  = 14;
	arrLookup[0][7]  = 4;
	
	arrLookup[1][0]  = 6;
	arrLookup[1][1]  = 6;
	arrLookup[1][2]	 = 9;
	arrLookup[1][3]  = 10;
	arrLookup[1][4]  = 5;
	arrLookup[1][5]  = 6;
	arrLookup[1][6]	 = 5;
	arrLookup[1][7]  = 5;

	arrLookup[2][0]  = 9;
	arrLookup[2][1]  = 9;
	arrLookup[2][2]	 = 9;
	arrLookup[2][3]  = 9;
	arrLookup[2][4]  = 9;
	arrLookup[2][5]  = 9;
	arrLookup[2][6]	 = 9;
	arrLookup[2][7]  = 9;

	arrLookup[3][0]  = 9;
	arrLookup[3][1]  = 9;
	arrLookup[3][2]	 = 4;
	arrLookup[3][3]  = 5;
	arrLookup[3][4]  = 10;
	arrLookup[3][5]  = 10;
	arrLookup[3][6]	 = 10;
	arrLookup[3][7]  = 8;

	arrLookup[4][0]  = 16;
	arrLookup[4][1]  = 12;
	arrLookup[4][2]  = 12;
	arrLookup[4][3]  = 12;
	arrLookup[4][4]  = 13;
	arrLookup[4][5]  = 11;
	arrLookup[4][6]  = 10;
	arrLookup[4][7]  = 13;
	
	arrLookup[5][0]  = 13;
	arrLookup[5][1]  = 6;
	arrLookup[5][2]	 = 7;
	arrLookup[5][3]  = 13;
	arrLookup[5][4]  = 11;
	arrLookup[5][5]  = 16;
	arrLookup[5][6]	 = 13;
	arrLookup[5][7]  = 13;
	
	arrLookup[6][0]  = 11;
	arrLookup[6][1]  = 13;
	arrLookup[6][2]	 = 12;
	arrLookup[6][3]  = 10;
	arrLookup[6][4]  = 12;
	arrLookup[6][5]  = 13;
	arrLookup[6][6]	 = 12;
	arrLookup[6][7]  = 17;
	
	arrLookup[7][0]  = 13;
	arrLookup[7][1]  = 13;
	arrLookup[7][2]	 = 11;
	arrLookup[7][3]  = 6;
	arrLookup[7][4]  = 5;
	arrLookup[7][5]  = 6;
	arrLookup[7][6]	 = 8;
	arrLookup[7][7]  = 9;

	arrLookup[8][0]  = 6;
	arrLookup[8][1]  = 8;
	arrLookup[8][2]  = 9;
	arrLookup[8][3]  = 8;
	arrLookup[8][4]  = 9;
	arrLookup[8][5]  = 8;
	arrLookup[8][6]  = 6;
	arrLookup[8][7]  = 8;
					 
	arrLookup[9][0]  = 9;
	arrLookup[9][1]  = 4;
	arrLookup[9][2]	 = 5;
	arrLookup[9][3]  = 9;
	arrLookup[9][4]  = 4;
	arrLookup[9][5]  = 14;
	arrLookup[9][6]	 = 9;
	arrLookup[9][7]  = 9;
	
	arrLookup[10][0] = 9;
	arrLookup[10][1] = 9;
	arrLookup[10][2] = 6;
	arrLookup[10][3] = 7;
	arrLookup[10][4] = 5;
	arrLookup[10][5] = 9;
	arrLookup[10][6] = 9;
	arrLookup[10][7] = 13;
					   
	arrLookup[11][0] = 8;
	arrLookup[11][1] = 9;
	arrLookup[11][2] = 8;
	arrLookup[11][3] = 9;
	arrLookup[11][4] = 3;
	arrLookup[11][5] = 9;
	arrLookup[11][6] = 10;
	arrLookup[11][7] = 14;

	arrLookup[12][0] = 9;
	arrLookup[12][1] = 14;
	arrLookup[12][2] = 6;
	arrLookup[12][3] = 9;
	arrLookup[12][4] = 8;
	arrLookup[12][5] = 18;
	arrLookup[12][6] = 9;
	arrLookup[12][7] = 9;
					   
	arrLookup[13][0] = 0;
	arrLookup[13][1] = 0;
	arrLookup[13][2] = 0;
	arrLookup[13][3] = 0;
	arrLookup[13][4] = 0;
	arrLookup[13][5] = 0;
	arrLookup[13][6] = 0;
	arrLookup[13][7] = 0;

	arrLookup[14][0] = 0;
	arrLookup[14][1] = 0;
	arrLookup[14][2] = 0;
	arrLookup[14][3] = 0;
	arrLookup[14][4] = 0;
	arrLookup[14][5] = 0;
	arrLookup[14][6] = 0;
	arrLookup[14][7] = 0;

	arrLookup[15][0] = 0;
	arrLookup[15][1] = 0;
	arrLookup[15][2] = 0;
	arrLookup[15][3] = 0;
	arrLookup[15][4] = 0;
	arrLookup[15][5] = 0;
	arrLookup[15][6] = 0;
	arrLookup[15][7] = 0;

	arrLookup[16][0] = 0;
	arrLookup[16][1] = 0;
	arrLookup[16][2] = 0;
	arrLookup[16][3] = 0;
	arrLookup[16][4] = 0;
	arrLookup[16][5] = 0;
	arrLookup[16][6] = 0;
	arrLookup[16][7] = 0;

	arrLookup[17][0] = 0;
	arrLookup[17][1] = 0;
	arrLookup[17][2] = 0;
	arrLookup[17][3] = 0;
	arrLookup[17][4] = 0;
	arrLookup[17][5] = 0;
	arrLookup[17][6] = 0;
	arrLookup[17][7] = 0;

	arrLookup[18][0] = 0;
	arrLookup[18][1] = 0;
	arrLookup[18][2] = 0;
	arrLookup[18][3] = 0;
	arrLookup[18][4] = 0;
	arrLookup[18][5] = 0;
	arrLookup[18][6] = 0;
	arrLookup[18][7] = 0;

	arrLookup[19][0] = 0;
	arrLookup[19][1] = 0;
	arrLookup[19][2] = 0;
	arrLookup[19][3] = 0;
	arrLookup[19][4] = 0;
	arrLookup[19][5] = 0;
	arrLookup[19][6] = 0;
	arrLookup[19][7] = 0;

	arrLookup[20][0] = 13;
	arrLookup[20][1] = 13;
	arrLookup[20][2] = 13;
	arrLookup[20][3] = 13;
	arrLookup[20][4] = 13;
	arrLookup[20][5] = 13;
	arrLookup[20][6] = 16;
	arrLookup[20][7] = 12;

	arrLookup[21][0] = 11;
	arrLookup[21][1] = 11;
	arrLookup[21][2] = 11;
	arrLookup[21][3] = 11;
	arrLookup[21][4] = 6;
	arrLookup[21][5] = 6;
	arrLookup[21][6] = 6;
	arrLookup[21][7] = 6;

	arrLookup[22][0] = 13;
	arrLookup[22][1] = 13;
	arrLookup[22][2] = 13;
	arrLookup[22][3] = 13;
	arrLookup[22][4] = 13;
	arrLookup[22][5] = 13;
	arrLookup[22][6] = 13;
	arrLookup[22][7] = 10;
	
	arrLookup[23][0] = 13;
	arrLookup[23][1] = 13;
	arrLookup[23][2] = 13;
	arrLookup[23][3] = 13;
	arrLookup[23][4] = 13;
	arrLookup[23][5] = 13;
	arrLookup[23][6] = 10;
	arrLookup[23][7] = 9;

	arrLookup[24][0] = 8;
	arrLookup[24][1] = 8;
	arrLookup[24][2] = 8;
	arrLookup[24][3] = 8;
	arrLookup[24][4] = 8;
	arrLookup[24][5] = 8;
	arrLookup[24][6] = 12;
	arrLookup[24][7] = 8;
	
	arrLookup[25][0] = 8;
	arrLookup[25][1] = 8;
	arrLookup[25][2] = 8;
	arrLookup[25][3] = 8;
	arrLookup[25][4] = 5;
	arrLookup[25][5] = 5;
	arrLookup[25][6] = 5;
	arrLookup[25][7] = 5;
	
	arrLookup[26][0] = 9;
	arrLookup[26][1] = 9;
	arrLookup[26][2] = 9;
	arrLookup[26][3] = 9;
	arrLookup[26][4] = 9;
	arrLookup[26][5] = 9;
	arrLookup[26][6] = 9;
	arrLookup[26][7] = 10;
	
	arrLookup[27][0] = 9;
	arrLookup[27][1] = 9;
	arrLookup[27][2] = 9;
	arrLookup[27][3] = 9;
	arrLookup[27][4] = 9;
	arrLookup[27][5] = 9;
	arrLookup[27][6] = 9;
	arrLookup[27][7] = 9;

	this->LookupTable = new int*[28];

	for(int i = 0; i < m_nNumRows; i++)
	{
		LookupTable[i] = nullptr;
		LookupTable[i] = new int[8];
	}

	for(int x = 0; x < m_nNumRows; x++)
		for(int y = 0; y < m_nNumCols; y++)
			LookupTable[x][y] = arrLookup[x][y];
}